Passed
Push — master ( 384857...16dbaf )
by Matt
08:13 queued 03:06
created

map.js ➔ addPhotos   A

Complexity

Conditions 3

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 11
c 0
b 0
f 0
dl 0
loc 18
rs 9.85
1
// TODO: Refactor the heck out of this mess
2
3
/* LeafletJS */
4
/** global: L */
5
/* global L */ /* For ESLint */
6
7
const $ = require('jquery');
8
import 'leaflet/dist/leaflet.css';
9
import 'leaflet-loading/src/Control.Loading.css';
10
import 'leaflet.locatecontrol/dist/L.Control.Locate.css';
11
import './styles/Leaflet.Photo.css';
12
13
require('leaflet');
14
require('leaflet.locatecontrol');
15
require('leaflet-loading');
16
require('leaflet.markercluster');
17
require('./Leaflet.Photo');
18
19
var streetMap;
20
var satelliteMap;
21
22
var base = L.latLng($("#mapid").data("homebaseLat"), $("#mapid").data("homebaseLng"));
23
24
export function setUpMap(options)
25
{
26
    var mapboxAccessToken = $("#mapid").data("mapboxAccessToken");
27
    var locusRadius = 1609.34; // 1 mile
28
29
    streetMap = L.tileLayer(
30
        "https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}@2x?access_token=" + mapboxAccessToken,
31
        {
32
            // These are mapbox-specific
33
            id: "gothick/ckhb31na304g619t67r3gcngx",
34
            tileSize: 512,
35
            zoomOffset: -1,
36
            // More general
37
            maxZoom: 19,
38
            attribution: "Map data &copy; <a href='https://www.openstreetmap.org/'>OpenStreetMap</a> contributors, <a href='https://creativecommons.org/licenses/by-sa/2.0/'>CC-BY-SA</a>, Imagery © <a href='https://www.mapbox.com/'>Mapbox</a>"
39
        });
40
41
    satelliteMap = L.tileLayer(
42
        "https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}@2x?access_token=" + mapboxAccessToken,
43
        {
44
            // These are mapbox-specific
45
            id: "gothick/ckhwgr59r0uai19o077hp87w4",
46
            tileSize: 512,
47
            zoomOffset: -1,
48
            // More general
49
            maxZoom: 19,
50
            attribution: "Map data &copy; <a href='https://www.openstreetmap.org/'>OpenStreetMap</a> contributors, <a href='https://creativecommons.org/licenses/by-sa/2.0/'>CC-BY-SA</a>, Imagery © <a href='https://www.mapbox.com/'>Mapbox</a>"
51
        });
52
53
    var circle = L.circle(base, {
54
        color: "green",
55
        fillColor: "#faa",
56
        fillOpacity: 0.15,
57
        radius: locusRadius,
58
        interactive: false
59
    });
60
61
    // Because Object.assign isn't supported in older browsers
62
    // TODO You can go back to Object.assign now you've started using Babel in
63
    // Webpack. It'll translate for you.
64
    // https://stackoverflow.com/a/41455739/300836
65
    $.extend(options, {
66
        maxBounds: base.toBounds(locusRadius * 5), // Give a bit of wiggle room around the circle, but don"t let the user drift too far away
67
        layers: [streetMap, circle],
68
        loadingControl: true, // https://github.com/ebrelsford/Leaflet.loading
69
        tap: false, // https://github.com/domoritz/leaflet-locatecontrol#safari-does-not-work-with-leaflet-171
70
    });
71
72
    var map = L.map("mapid", options)
73
        .setView(base, 14);
74
75
    var baseMaps = {
76
        "Satellite": satelliteMap,
77
        "Streets": streetMap
78
    };
79
80
    L.control.layers(baseMaps).addTo(map);
81
    L.control.scale().addTo(map);
82
83
    L.control.locate().addTo(map);
84
85
    return map;
86
}
87
88
function selectedWanderStyle() {
89
    return {
90
        weight: 5,
91
        color: "#FFA500"
92
    };
93
}
94
95
function unselectedWanderStyle() {
96
    return {
97
        weight: 4,
98
        color: "#3388FF"
99
    };
100
}
101
102
var currentlySelected = null;
103
104
 var photoLayer = null;
105
106
export function addPhotos(map, photos)
107
    {
108
    if (photoLayer) {
109
        map.removeLayer(photoLayer);
110
    }
111
112
    photoLayer = L.photo.cluster().on("click", function(evt) {
113
        var photo = evt.layer.photo;
114
        var template = "<a href='{imageShowUri}'><img src='{url}' width='300' /></a><p>{caption}</p>";
115
        // TODO: Video
116
        evt.layer.bindPopup(L.Util.template(template, photo), {
117
            className: "leaflet-popup-photo",
118
            minWidth: 300
119
        }).openPopup();
120
    });
121
122
    photoLayer.add(photos).addTo(map);
123
}
124
125
function addWanderImages(map, wanderId)
126
{
127
    var photos = [];
128
129
    // Our API allows us to grab only those photos with co-ordinates set
130
    $.getJSON("/api/wanders/" + wanderId + "/images?exists[latlng]=true", function(images) {
131
        $.each(images["hydra:member"], function(key, image) {
132
            photos.push({
133
                lat: image.latlng[0],
134
                lng: image.latlng[1],
135
                url: image.mediumImageUri,
136
                caption: image.title || "",
137
                thumbnail: image.markerImageUri,
138
                imageShowUri: image.imageShowUri,
139
                // TODO?
140
                video: null
141
            });
142
        });
143
        addPhotos(map, photos);
144
    });
145
}
146
147
function addWanders(url, map)
148
{
149
    map.fireEvent('dataloading'); // Triggers loading spinner
150
    // TODO: We should probably use some kind of Hydra client. This"ll do for now.
151
    $.getJSON(url, function(data) {
152
        var nextPage = (data["hydra:view"] || {})["hydra:next"];
153
        var isLastPage = (typeof nextPage) == 'undefined';
154
        var last = data["hydra:member"].length - 1;
155
        $.each(data["hydra:member"], function(key, wander) {
156
            var isLastWander = isLastPage && (last === key);
157
            var geoJsonFeature = {
158
                "type": "Feature",
159
                "geometry":  $.parseJSON(wander.geoJson)
160
            };
161
            var geoJsonTrack = L.geoJSON(
162
                geoJsonFeature,
163
                {
164
                    style: isLastWander ? selectedWanderStyle() : unselectedWanderStyle(),
165
                    wanderId: wander.id
166
                })
167
                .bindPopup(function(layer) {
168
                    currentlySelected.setStyle(unselectedWanderStyle());
169
                    layer.setStyle(selectedWanderStyle());
170
                    layer.bringToFront();
171
                    currentlySelected = layer;
172
                    addWanderImages(map, layer.options.wanderId);
173
                    // Popup
174
                    var template = "<a href='{contentUrl}'>{title}</a>";
175
                    return L.Util.template(template, wander);
176
                });
177
178
            if (isLastWander) {
179
                currentlySelected = geoJsonTrack;
180
            }
181
            geoJsonTrack.addTo(map);
182
        });
183
184
        // Recurse through all the pages in the pagination we got back.
185
        map.fireEvent("dataload");
186
        if (!isLastPage) {
187
            addWanders(nextPage, map);
188
        }
189
    });
190
}
191
192
export function addAllWanders(map)
193
{
194
    addWanders("/api/wanders", map);
195
}
196
197
export function addWander(map, wanderId, addImages)
198
{
199
    $.getJSON("/api/wanders/" + wanderId, function(wander) {
200
        var geoJsonFeature = {
201
            "type": "Feature",
202
            "geometry": $.parseJSON(wander.geoJson)
203
        };
204
        L.geoJSON(geoJsonFeature)
205
            .bindPopup(function(/* layer */) {
206
                return wander.title;
207
            })
208
            .addTo(map);
209
        // Based on the example at https://github.com/turban/Leaflet.Photo/blob/gh-pages/examples/picasa.html
210
        if (addImages) {
211
            addWanderImages(map, wanderId);
212
        }
213
    });
214
}
215